package com.mrslu.signkk.interceptor;

import com.mrslu.signkk.pojo.User;
import com.mrslu.signkk.pojo.identity.UserRoleEnum;
import com.mrslu.signkk.util.StringConstValue;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author 卢斌
 */
@Component
public class TokenCensor {

    private final RedisTemplate<String, String> redisTemplate;

    @Value("${login-available-time}")
    private Long tokenEffectTime;

    @Autowired
    public TokenCensor(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * Token构造
     *
     * @param userId        用户Id
     * @param userRole      用户身份
     * @param sessionKey    一个随意字符串
     * @return  token
     */
    private String buildToken(Integer userId, UserRoleEnum userRole, Integer orgId, String sessionKey) {
        JwtBuilder jwtBuilder = Jwts.builder().setId(userId.toString()).setSubject(userRole.toString() + StringConstValue.STUB + orgId)
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, sessionKey);
        return jwtBuilder.compact();
    }

    public String tokenIssue(Integer userId, UserRoleEnum userRole, Integer orgId, String sessionKey) {
        String token = this.buildToken(userId, userRole, orgId, sessionKey);
        redisTemplate.opsForValue().set(token, sessionKey, tokenEffectTime, TimeUnit.SECONDS);
        return token;
    }


    public User parseToken(String tokenStr, String sessionKey) {
        Claims claims = Jwts.parser().setSigningKey(sessionKey).parseClaimsJws(tokenStr).getBody();
        User dto = new User();
        dto.setId(Integer.parseInt(claims.getId()));
        String subject = claims.getSubject();
        String[] subjectParam = subject.split(StringConstValue.STUB.toString());
        dto.setUserRole(UserRoleEnum.parseUserRole(subjectParam[0]));
        dto.setOrgId(Integer.valueOf(subjectParam[1]));
        return dto;
    }

}